@/******************************************************************************
@ * @file     cpureg_test_startup.s
@ * @version  V0.10
@ * $Revision: 2 $
@ * $Date: 21/03/08 8:07p $
@ * @brief    IIEC60730 CPU Register Test at Startup Time
@ * @note
@ * SPDX-License-Identifier: Apache-2.0
@ * Copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
@ ******************************************************************************/

.global IEC60730_CPU_Reg_Test
@   IMPORT	u8CPUTestPass

.equ pattern1, 0x55555555
.equ pattern2, 0xAAAAAAAA

IEC60730_CPU_Reg_Test:
@push registers to stack
	push	{r0-r7}

@disable all interrupt
	mrs		r0, CPSR
	push	{r0-r7}
	orr		r0, r0, #0x000000C0	@I-bit(7), F-bit(6) disabled
	msr		CPSR_c, r0
	mrs		r0, CPSR 			@ for checking CPSR

@===========R0 Test=============
@compare bit 0-7
	movs	r0, #0xAA
	cmp		r0, #0xAA           @For SW test breakpoint
	bne     _test_r0_fail
	movs	r0, #0x55
	cmp		r0, #0x55
	bne     _test_r0_fail

@compare bit 8-15
	ldr		r0, =0x0000AA00
	lsrs    r0, r0, #8
	cmp		r0, #0xAA           @For SW test breakpoint
	bne     _test_r0_fail
	ldr		r0, =0x00005500
	lsrs    r0, r0, #8
	cmp		r0, #0x55
	bne     _test_r0_fail

@compare bit 16-23
	ldr		r0, =0x00AA0000
	lsrs    r0, r0, #16
	cmp		r0, #0xAA           @For SW test breakpoint
	bne     _test_r0_fail
	ldr		r0, =0x00550000
	lsrs    r0, r0, #16
	cmp		r0, #0x55
	bne     _test_r0_fail

@compare bit 24-31
	ldr		r0, =0xAA000000
	lsrs    r0, r0, #24
	cmp		r0, #0xAA           @For SW test breakpoint
	bne     _test_r0_fail
	ldr		r0, =0x55000000
	lsrs    r0, r0, #24
	cmp		r0, #0x55
	bne     _test_r0_fail
	b		_reg_test_r1_r7

_test_r0_fail:
@enable interrupt
	pop		{r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
    pop     {r0-r7}

@==test fail==
    movs    r0, #0x00
@branch back
	bx      lr
@===============================

@=========R1 - R7 Test==========
_reg_test_r1_r7:
    ldr		r1, =pattern1
    ldr		r0, =pattern1
    cmp		r1, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r1, =pattern2
    ldr		r0, =pattern2
    cmp		r1, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r2, =pattern1
    ldr		r0, =pattern1
    cmp		r2, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r2, =pattern2
    ldr		r0, =pattern2
    cmp		r2, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r3, =pattern1
    ldr		r0, =pattern1
    cmp		r3, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r3, =pattern2
    ldr		r0, =pattern2
    cmp		r3, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r4, =pattern1
    ldr		r0, =pattern1
    cmp		r4, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r4, =pattern2
    ldr		r0, =pattern2
    cmp		r4, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r5, =pattern1
    ldr		r0, =pattern1
    cmp		r5, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r5, =pattern2
    ldr		r0, =pattern2
    cmp		r5, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r6, =pattern1
    ldr		r0, =pattern1
    cmp		r6, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r6, =pattern2
    ldr		r0, =pattern2
    cmp		r6, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r7, =pattern1
    ldr		r0, =pattern1
    cmp		r7, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    ldr		r7, =pattern2
    ldr		r0, =pattern2
    cmp		r7, r0                  @For SW test breakpoint
    bne 	_test_r1_r7_fail
    b		_reg_test_r8_r12

_test_r1_r7_fail:
@enable interrupt
    pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
    pop     {r0-r7}

@==test fail==
    movs    r0, #0x00
@branch back
	bx      lr
@===============================

@=========R8 - R12 Test=========
_reg_test_r8_r12:
@store r8-r12
	mov		r3, r8
	mov 	r4, r9
	mov 	r5, r10
	mov 	r6, r11
	mov 	r7, r12

	ldr		r8, =pattern1
	ldr		r0, =pattern1
	cmp		r8, r0                  @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r8, =pattern2
	ldr		r0, =pattern2
	cmp		r8, r0                  @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r9, =pattern1
	ldr		r0, =pattern1
	cmp		r9, r0                  @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r9, =pattern2
	ldr		r0, =pattern2
	cmp		r9, r0                  @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r10, =pattern1
	ldr		r0, =pattern1
	cmp		r10, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r10, =pattern2
	ldr		r0, =pattern2
	cmp		r10, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r11, =pattern1
	ldr		r0, =pattern1
	cmp		r11, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r11, =pattern2
	ldr		r0, =pattern2
	cmp		r11, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r12, =pattern1
	ldr		r0, =pattern1
	cmp		r12, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
	ldr		r12, =pattern2
	ldr		r0, =pattern2
	cmp		r12, r0                 @For SW test breakpoint
	bne 	_test_r8_r12_fail
@restore r8-r12
	mov 	r12, r7
	mov 	r11, r6
	mov 	r10, r5
	mov 	r9, r4
	mov 	r8, r3
	b		_reg_test_CPSR

_test_r8_r12_fail:
@enable interrupt
    pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
    pop     {r0-r7}
@restore r8-r12
	mov 	r12, r7
	mov 	r11, r6
	mov 	r10, r5
	mov 	r9, r4
	mov 	r8, r3

@==test fail==
    movs    r0, #0x00
@branch back
	bx      lr
@===============================

@=========CPSR Test=============
@ only bit-7 and bit-6 being tested
_reg_test_CPSR:
	mrs		r0, CPSR
	mrs		r1, CPSR
	and		r1, r1, #0xFFFFFF3F	@I-bit(7), F-bit(6) enabled
	msr		CPSR_c, r1
	mrs		r2, CPSR
	cmp		r2, r1
	bne		_test_cpsr_fail
	mrs		r1, CPSR
	orr		r1, r1, #0x000000C0	@I-bit(7), F-bit(6) disabled
	msr		CPSR_c, r1
	mrs		r2, CPSR
	cmp		r2, r1
	bne		_test_cpsr_fail
	msr 	CPSR_c, r0
	b		_reg_test_SP

_test_cpsr_fail:
	pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR                @For SW test breakpoint
@restore registers
	pop     {r0-r7}

@==test fail==
    movs    r0, #0x00
@branch back
	bx      lr
@===============================

@===========SP Test=============
_reg_test_SP:
@disable interrupt
	mrs		r0, CPSR
	orr		r0, r0, #0x000000C0	@I-bit(7), F-bit(6) disabled
	msr		CPSR_c, r0
	mrs		r0, CPSR                @For SW test breakpoint
@store SP
	mov     r3, r13
@check SP
	ldr		r1, =0xAAAAAAA8
	mov		r13, r1
	cmp		r13, r1                 @For SW test breakpoint
	bne 	_test_sp_fail
	ldr		r1, =0x55555554
	mov		r13, r1
	cmp		r13, r1                 @For SW test breakpoint
	bne 	_test_sp_fail
@restore SP
	mov     r13, r3
	b 		_reg_test_LR

_test_sp_fail:
@enable interrupt
	pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
	pop     {r0-r7}

@==test fail==
    movs    r0, #0x00
@branch back
	bx      lr
@===============================

@===========LR Test=============
_reg_test_LR:
	mov		r0, r14
	ldr		r1, =0x55555555
	mov 	r14, r1
	cmp		r14, r1                 @For SW test breakpoint
	bne		_test_lr_fail
	ldr		r1, =0xAAAAAAAA
	mov 	r14, r1
	cmp		r14, r1                 @For SW test breakpoint
	bne		_test_lr_fail
	mov 	r14, r0
	b		_test_cpu_reg_pass

_test_lr_fail:
@enable interrupt
	pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
	pop     {r0-r7}

@==test fail==
    movs    r0, #0x00

@branch back
	bx      lr
@===============================

_test_cpu_reg_pass:
@	ldr     r1, =u8CPUTestPass
@	movs    r0, #0x01
@	str     r0, [r1]
	pop     {r0-r7}
	msr		CPSR_c, r0
	mrs		r0, CPSR
@restore registers
	pop     {r0-r7}

@==test pass==
    movs    r0, #0x01

@branch back
	bx      lr
	NOP